import json
import re
from venv import logger

from rest_framework import serializers
from rest_framework.generics import RetrieveUpdateAPIView, UpdateAPIView
from rest_framework.permissions import IsAuthenticated
import random
from django.http import JsonResponse
from rest_framework_jwt.settings import api_settings
from celery_tasks.yuntongxun.ccp_sms import CCP
from users.models import User
from users.myserializer import AuthSerializer  # LoginUserSerializer
from celery_tasks.sms.tasks import send_sms_code_func

import random

from django.contrib.auth import authenticate, login
from django.http import Http404, JsonResponse
from django.shortcuts import render

# Create your views here.
from django.views import View
from django_redis import get_redis_connection
from rest_framework import status
from rest_framework.generics import CreateAPIView
from rest_framework.response import Response
from rest_framework.views import APIView
from celery_tasks.yuntongxun.ccp_sms import CCP
from users.models import User
from users.myserializer import AuthSerializer
from users.serializers import UserLogSerializer, UserSerializer, UserLabelSerializer, SetPwdSerializer


class UserInFoView(RetrieveUpdateAPIView):
    #揣培洋 -- 8.1 获取个人详情 GET/user/
    serializer_class = UserSerializer
    permission_classes = [IsAuthenticated]

    def get_object(self):
        user = self.request.user
        replies = user.replies.all()
        user.answer_question = []
        for item in replies:
            if item.type == 2:
                user.answer_question.append(item)
        return user



class UserLabelView(UpdateAPIView):
    # 揣培洋 -- 8.2 修改个人信息 PUT/user/
    permission_classes = [IsAuthenticated]
    serializer_class = UserLabelSerializer

    def get_object(self):
        return self.request.user





class SetPwdView(UpdateAPIView):
    #揣培洋 -- 8.3 修改密码 PUT/user/passsword
    permission_classes = [IsAuthenticated]
    serializer_class = SetPwdSerializer

    def get_object(self):
        return self.request.user




class UserLikeView(APIView):
    #揣培洋 --  8.4;8.5 关注--取消关注 POST/ user/like/{id}/
    permission_classes = [IsAuthenticated]

    # 当前用户关注id
    def post(self, request, id):
        user = self.request.user
        id_1 = User.objects.get(id=id)
        if id_1 in user.idols.all():
            return Response({"success": False, "message": "不要再来了"}, status=400)
        user.idols.add(id_1)
        user.save()
        return Response({"success": True, "message": "关注成功"})

    # 当前用户取消关注id
    def delete(self, request, id):
        user = self.request.user
        id_2 = User.objects.get(id=id)
        if id_2 not in user.idols.all():
            return Response({"success": False, "message": "不要再来了"}, status=400)
        user.idols.remove(id_2)
        user.save()
        return Response({"success": True, "message": "取消关注成功"})




# # 李东晨 -- 2.2 注册 POST /users/(视图)
# class UserRegisterView(APIView):
#     def post(self, request):
#         # 接收成参数
#         json_bytes = request.body
#         json_dict = json.loads(json_bytes)
#         username = json_dict.get('username')
#         password = json_dict.get('password')
#         mobile = json_dict.get('mobile')
#         sms_code_client = json_dict.get('sms_code')
#         redis_conn = get_redis_connection('sms_code')
#         # 验证短信验证码是否过期
#         try:
#             sms_code_server = redis_conn.get('sms_%s' %mobile).decode()
#         except:
#             return JsonResponse({'type': 'error', 'data': '验证码失效'})
#         # 校验参数完整性
#         if not all([username, password, mobile, sms_code_client]):
#             return JsonResponse({'type': 'error', 'data': '缺少必传参数'})
#         # 检验验证码是否输入正确
#         if sms_code_client != sms_code_server:
#             return JsonResponse({'type': 'error', 'data': '验证码输入有误'})
#         if not (len(password) < 6 | len(password) > 20):
#             # return response.senderror({'status': 'error', 'data': '密码长度有误'})
#             raise Http404
#         # 将用户数据保存到数据库
#         user = User.objects.create_user(username=username,
#                             password=password,
#                             mobile=mobile)
#         # 生成token
#         user = create(user)
#         # 状态保持
#         login(request, user)
#         # 返回前端
#         return JsonResponse({'username':user.nickname,
#                              'id':user.id,
#                              'mobile':user.mobile,
#                              'token':user.token,
#                              'sms_code':sms_code_client,
#                              'type':'success',
#                             })
#
# def create(user):
#     # 服务器生成jwt token, 保存当前用户的身份信息
#     from rest_framework_jwt.settings import api_settings
#     # 组织payload数据的方法
#     jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
#     # 生成jwt token数据的方法
#     jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
#     # 组织payload数据
#     payload = jwt_payload_handler(user)
#     # 生成jwt token
#     token = jwt_encode_handler(payload)
#     # 给user对象增加属性，保存jwt token的数据
#     user.token = token
#     # 返回前端
#     return user
#
#
# # 李东晨 -- 2.2 登录 POST /authorizations/(视图)
# class UserLoginView(APIView):
#     def post(self, request):
#         # 接收参数
#         json_bytes = request.body
#         json_dict = json.loads(json_bytes)
#         username = json_dict.get('username')
#         password = json_dict.get('password')
#         remember = json_dict.get('remember')
#         # 校验参数完整性
#         if not all([username, password]):
#             return JsonResponse({'code': 400, 'errmsg': '缺少必传参数'})
#         # 检验用户名和密码
#         user = authenticate(username=username,
#                             password=password)
#         # 如果校验失败，返回前端
#         if user is None:
#             return JsonResponse({'type': 'error'})
#         # 生成JWT token
#         user = create(user)
#         # 状态保持
#         login(request, user)
#         # 如果没有勾选记住登录状态
#         if remember!=True:
#             request.session.set_expiry(0)
#         # 如果勾选登录状态
#         else:
#             request.session.set_expiry(None)
#         # 返回前端
#         return JsonResponse({'username': user.username,
#                              'id': user.id,
#                              'mobile': user.mobile,
#                              'token': user.token,
#                              'tpye': 'success'
#                              })
#
# # 李东晨 -- 2.2 短信验证码 GET /sms_codes/(?P<mobile>.*?)(视图)
# class SendSmscodeView(View):
#     def get(self, request, mobile):
#         # 校验手机号是否输入正确
#         if not re.match(r'^1[3-9]\d{9}$', mobile):
#             return JsonResponse({'type': 'error', 'message': '手机号输入有误'})
#         # 检查是否重复发送短信
#         redis_conn = get_redis_connection('verify_code')
#         sms_code_file = redis_conn.get('sms_code_flag_%s' % mobile)
#         if sms_code_file:
#             return JsonResponse({'type': 'error', 'message': '频繁发送短信验证码'})
#         # 手机号已注册
#         try:
#             User.objects.get(mobile=mobile)
#             return JsonResponse({'type': 'error', 'message': '手机号已注册'})
#         # 手机号未注册
#         except:
#             # 生产验证码
#             sms_code = '%04d' % random.randint(0, 9999)
#             # 将验证码保存在日志
#             logger.info(sms_code)
#             # 创建管道操作redis数据库
#             pl = redis_conn.pipeline()
#             # 将短信验证码保存在redis数据库
#             pl.setex('sms_%s' % mobile, 300, sms_code)
#             # 将手机号设置一个标记，时间为60s,防止用户频繁发送短信
#             pl.setex('sms_code_flag_%s' % mobile, 60, 1)
#             # 执行管道操作
#             pl.execute()
#             # 发送短信
#             send_sms_code_func.delay(mobile, sms_code)
#             # 返回前端
#             return JsonResponse({'success':100,
#                                  'sms_code':sms_code
#                                  })


class Sms_code(View):
    def get(self, request, mobile):
        redis_conn = get_redis_connection("verify_code")
        sms_code_file = redis_conn.get('send_file_%s' % mobile)

        if sms_code_file:
            return JsonResponse({'code': 400,
                                 'errmsg': '发送过于频繁'})
        sms_code = "%06d" % random.randint(0, 999999)
        pl = redis_conn.pipeline()
        pl.setex("sms_%s" % mobile, 300, sms_code)
        pl.setex("send_file_%s" % mobile, 60, 1)
        pl.execute()
        CCP().send_template_sms(mobile, [sms_code, 5], 1)
        return JsonResponse({
            "success": True,
            "sms_code": sms_code,
            "message": "ok"
        })


class LoginAuthView(CreateAPIView):
    serializer_class =  AuthSerializer
    queryset = User.objects.all()

class UserLogin(APIView):
    def post(self, request):
        serializer = UserLogSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        serializer.save()
        return Response(serializer.data)